#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'wshu'
__version__ = '1.0'
"""
    ***********************************
    *  @filename : strategyview.py
    *  @Author : wshu
    *  @CodeDate : 2020/4/22 17:05
    *  @Software : PyCharm
    ***********************************
"""
import time
import datetime
import tornado.escape
from core import BaseHandlers
from Ui.HFmSetting.utils.functional import paging
from Ui.HFmSetting.utils.checktool import check_task_name
from db.mysql import Strategy, KeywordStrategy, TextStrategy
from sqlalchemy import func, or_, and_, desc
from core.comm.http.JsonResponse import Jsonify, JsonForm

class StrategyViewHandler(BaseHandlers):
    """
    策略视图
    """
    error_msg = ''

    def get(self, *args, **kwargs):
        self.render('strategy/strategyview.html', error_msg=self.error_msg)

class StrategyDeleteHandler(BaseHandlers):
    """
    策略删除
    """
    error_msg = ''

    def post(self, *args, **kwargs):
        self.write('ok')

# *************
# ***关键词策略管理
# *************
class StrategyAddHandler(BaseHandlers):
    """
    关键词策略添加
    """
    error_msg = ''

    def get(self, *args, **kwargs):
        self.render('strategy/keyword_add.html', error_msg=self.error_msg)

    def post(self, *args, **kwargs):
        title = self.get_argument('name')
        desc = self.get_argument('desc')
        keywords = self.get_argument('keyword_list')
        # 生成策略ID
        try:
            latest_id = self.db.query(Strategy).filter(Strategy.id == self.db.query(func.max(Strategy.id))).first().id
        except AttributeError:
            latest_id = 0
        latest_id += 1
        strategy_id = str('s') + time.strftime('%Y%m%d', time.localtime(time.time())) + str(latest_id)
        # 检查输入策略名称是否合规
        if check_task_name(title):
            # 检查该策略是否存在
            is_task_exists = self.db.query(Strategy).filter_by(strategy_name=title).first()
            if not is_task_exists:
                # 策略存储
                strategy_get = Strategy(
                    strategy_id=strategy_id,
                    strategy_name=title,
                    describe=desc,
                )
                self.db.add(strategy_get)
                self.db.flush()
                strategy_id = strategy_get.strategy_id
                # 去除空白字符
                keyword_list_tab = keywords.replace(' ', '')
                keyword_get_list = keyword_list_tab.split('\n')
                while "" in keyword_get_list: keyword_get_list.remove("")

                keyword_get = [KeywordStrategy(
                    keyword=kw_item,
                    strategy_id=strategy_id
                ) for kw_item in keyword_get_list]
                # FIXME: 没有进行输入过滤？
                self.db.bulk_save_objects(keyword_get)
                try:
                    self.db.commit()
                except:
                    # db error：事务回滚
                    self.db.rollback()
                # 添加成功返回
                self.error_msg = JsonForm(status='success', msg="策略添加成功").Dict
            else:
                self.error_msg = JsonForm(status='error', msg="添加失败，该策略名称已存在").Dict
        else:
            self.error_msg = JsonForm(status='error', msg="禁止非法输入哦，策略长度不超过15，仅支持中文、字母、数字、下划线").Dict
        self.write(self.error_msg)

class StrategyKeywordListHandler(BaseHandlers):
    """
    关键词策略列表
    用处: 用于显示该用户自定义所有的关键词策略，不具体展示关键词详情
    1. 策略名称
    2. 策略描述
    3. 该策略内关键词数量
    4. 创建时间
    """
    error_msg = ''

    @staticmethod
    def get_count(Q):
        count_query = Q.statement.with_only_columns([func.count()]).order_by(None)
        count = Q.session.execute(count_query).scalar()
        return count

    def post(self, *args, **kwargs):
        page = self.get_argument('page', None)
        rows = self.get_argument('limit', None)
        strategy_name = self.get_argument('name', None)

        if not strategy_name:
            strategy_name = ''

        # 分页查询 p: 页 r: 条
        p, r = paging(page, rows)
        # 查询用户自定义策略
        strategy_get = self.db.query(Strategy).filter(Strategy.strategy_name.notlike(strategy_name))
        strategy_list = strategy_get.order_by(desc(Strategy.starttime)).slice(p, r).all()
        total = self.get_count(strategy_get)

        # 返回layui table数据格式
        laydata = []
        for strategy_item in strategy_list:
            tempDict = {}
            tempDict['onlykey'] = strategy_item.strategy_id
            tempDict['title'] = strategy_item.strategy_name
            tempDict['desc'] = strategy_item.describe
            tempDict['num'] = self.get_count(self.db.query(KeywordStrategy).filter(KeywordStrategy.strategy_id == strategy_item.strategy_id))
            tempDict['creat_at'] = strategy_item.starttime.strftime("%Y-%m-%d %H:%M:%S")
            # make layui data
            laydata.append(tempDict)
        # print("查询数据: ", laydata)
        # 以JSON形式返回数据
        json_data = Jsonify(
            code=0,
            msg="关键词策略",
            count=total,
            data=laydata).json()
        self.write(json_data)

    def delete(self, *args, **kwargs):
        """
        关键词策略删除，物理删除，删除策略同时会将该策略下所有的关键词一并删除
        FIXME: 是否可以考虑逻辑删除？但是会存在数据耦合？？
        """
        print('delete....')
        strategy_str = self.get_argument('strategy_list', None)
        action = self.get_argument('action', None)
        strategy_list = tornado.escape.json_decode(strategy_str)
        if action == 'start':
            for strategy_item in strategy_list:
                self.db.query(Strategy).filter(Strategy.strategy_name == strategy_item).delete()
            self.error_msg = JsonForm(status='success', msg='删除成功').Dict
            self.db.commit()
        else:
            if action == 'stop':
                pass
            self.error_msg = JsonForm(status='error', msg='删除失败').Dict
        self.write(self.error_msg)

class KeywordTableListHandler(BaseHandlers):
    """
    策略下关键词列表
    用处: 用于针对特定某一个策略下的关键词
    功能: 用于管理每个策略下关键词，添加/删除
    1. 关键词
    2. 高级操作
    """
    error_msg = ''

    @staticmethod
    def get_count(Q):
        count_query = Q.statement.with_only_columns([func.count()]).order_by(None)
        count = Q.session.execute(count_query).scalar()
        return count

    def get(self, strategy_id):
        # print("策略ID: ", strategy_id)
        self.render('strategy/keyword_list.html', error_msg=self.error_msg, s_id=strategy_id)

    def post(self, strategy_id):
        page = self.get_argument('page', None)
        rows = self.get_argument('limit', None)
        s_id = self.get_argument('s_id', None)

        # 分页查询 p: 页 r: 条
        p, r = paging(page, rows)
        # 按策略查询关键词
        keyword_get = self.db.query(KeywordStrategy).filter(KeywordStrategy.strategy_id == s_id)

        keyword_list = keyword_get.order_by(desc(KeywordStrategy.upadtetime)).slice(p, r).all()
        total = self.get_count(keyword_get)
        # 统计策略下关键词
        laydata = []
        for keyword_item in keyword_list:
            tempDict = {}
            tempDict['keyword'] = keyword_item.keyword
            laydata.append(tempDict)

        # 以JSON形式返回数据
        json_data = Jsonify(
            code=0,
            msg="关键词列表",
            count=total,
            data=laydata).json()
        self.write(json_data)

    def delete(self, strategy_id):
        """
        策略内关键词删除
        FIXME: 预处理方案，单独删除策略下的关键词，是否不需要此项删除？？
        """
        strategy_name = self.get_argument('strategy_name', None)
        strategy_str = self.get_argument('strategy_list', None)
        if strategy_str:
            strategy_list = tornado.escape.json_decode(strategy_str)
        else:
            strategy_list = ''

        action = self.get_argument('action', None)

        if not action and strategy_name is not None:
            self.db.query(KeywordStrategy).filter(KeywordStrategy.keyword == strategy_name).delete()
            self.db.commit()
            self.error_msg = JsonForm(status='success', msg='删除成功').Dict
        elif action == 'batch':
            for strategy_item in strategy_list:
                self.db.query(KeywordStrategy).filter(KeywordStrategy.keyword == strategy_item).delete()
            self.db.commit()
            self.error_msg = JsonForm(status='success', msg='删除成功').Dict
        else:
            self.error_msg = JsonForm(status='error', msg='删除失败').Dict
        self.write(self.error_msg)


class KeywordAddHandler(BaseHandlers):
    """
    关键词添加
    用处: 用于添加具体策略下的关键词
    功能: 添加关键词
    1. 所属策略
    2. 关键词输入
    """
    error_msg = ''

    def get(self, s_id):
        s_name = self.db.query(Strategy).filter(Strategy.strategy_id == s_id).first()
        self.render('strategy/keyword_edit.html', error_msg=self.error_msg, s_name=s_name, s_id=s_id)

    def post(self, s_id):
        # print('post.....')
        keyword_str = self.get_argument('keyword_list', None)
        s_id = self.get_argument('s_id', None)
        # 去除空白字符
        keyword_list_tab = keyword_str.replace(' ', '')
        keyword_get_list = keyword_list_tab.split('\n')
        while "" in keyword_get_list: keyword_get_list.remove("")

        # 具体策略下的关键词添加 EX: 苍井空、AV...每行一个词
        keyword_get = [KeywordStrategy(
            keyword=kw_item,
            strategy_id=s_id
        ) for kw_item in keyword_get_list]
        # FIXME: 没有进行输入过滤？
        self.db.bulk_save_objects(keyword_get)
        try:
            self.db.commit()
        except:
            self.db.rollback()
        # 添加成功返回
        self.error_msg = JsonForm(status='success', msg="关键词添加成功").Dict
        self.write(self.error_msg)

# *************
# ***文本策略管理
# *************
class StrategyTextHandler(BaseHandlers):
    """
    文本策略添加
    """
    error_msg = ''

    def get(self, *args, **kwargs):
        self.render('strategy/text_add.html', error_msg=self.error_msg)

    def post(self, *args, **kwargs):
        self.write('ok')

# *************
# ***图片策略管理
# *************
class StrategyImageHandler(BaseHandlers):
    """
    图片策略添加
    """
    error_msg = ''

    def get(self, *args, **kwargs):
        self.render('strategy/image_add.html', error_msg=self.error_msg)

    def post(self, *args, **kwargs):
        self.write('ok')
